home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / macros / latex209 / contrib / misc / tables.sty < prev    next >
Text File  |  1989-12-21  |  21KB  |  602 lines

  1. %  modified by Bob Taylor for University of Rochester 20-Mar-87:
  2. %  \line macro in Cowan's code is disabled by LaTeX, so I've
  3. %  changed all instances of \line in Cowan's code to the new
  4. %  definition \tableline as defined right after this comment.
  5. %
  6.    \def\tableline{\hbox to \hsize}
  7. %
  8. % +--------------------------------------------------------------------+
  9. % ]                                                                    ]
  10. % ]                           TABLES.TEX                               ]
  11. % ]                                                                    ]
  12. % ]                     Ray F. Cowan  15-Feb-85                        ]
  13. % ]                                                                    ]
  14. % ]                       Princeton University                         ]
  15. % ]                                                                    ]
  16. % ]                     Last Revision: 21-Nov-85                       ]
  17. % ]                                                                    ]
  18. % ]   Macros I find handy for making tables.  See TABLEDOC TEX for     ]
  19. % ]   a longer description.  The token-counting macros are straight    ]
  20. % ]   from the TeXbook's "Dirty Tricks" appendix.                      ]
  21. % ]                                                                    ]
  22. % +--------------------------------------------------------------------+
  23. %
  24. \newbox\hdbox%
  25. \newcount\hdrows%
  26. \newcount\multispancount%
  27. \newcount\ncase%
  28. \newcount\ncols% This is the number of primary text columns in the table.
  29. \newcount\nrows%
  30. \newcount\nspan%
  31. \newcount\ntemp%
  32. \newdimen\hdsize%
  33. \newdimen\newhdsize%
  34. \newdimen\parasize%
  35. \newdimen\spreadwidth%
  36. \newdimen\thicksize%
  37. \newdimen\thinsize%
  38. \newdimen\tablewidth%
  39. \newif\ifcentertables%
  40. \newif\ifendsize%
  41. \newif\iffirstrow%
  42. \newif\iftableinfo%
  43. \newtoks\dbt%
  44. \newtoks\hdtks%
  45. \newtoks\savetks%
  46. \newtoks\tableLETtokens%
  47. \newtoks\tabletokens%
  48. \newtoks\widthspec%
  49. %
  50. %  Book-keeping stuff--see how often these macros are called.
  51. %
  52. %\immediate\write15{%
  53. %CP SMSG GJMSINK TEXTABLE --> TABLE MACROS V. 851121 JOB = \jobname%
  54. %}%
  55. %
  56. %  Turn on table diagnostics.
  57. %
  58. \tableinfotrue%
  59. \catcode`\@=11%  Allows use of "@" in macro names, like PLAIN.TEX does.
  60. \def\out#1{\immediate\write16{#1}}%  Debugging aid.  Writes #1 on the
  61. %                                    user's terminal and in the log file.
  62. %
  63. %  Define the \tstrut height, depth in terms of the x_height parameter.
  64. %
  65. \def\tstrut{\vrule height3.1ex depth1.2ex width0pt}%
  66. \def\and{\char`\&}%  Allows us to get an `&' in the text.  This is the
  67. %                    same as using the PLAIN TeX macro \&.
  68. \def\tablerule{\noalign{\hrule height\thinsize depth0pt}}%
  69. \thicksize=1.5pt%  Default thickness for fat rules.  The user should feel
  70. %                  free to change this to his preference.
  71. \thinsize=0.6pt%   Default thickness for thin rules.
  72. \def\thickrule{\noalign{\hrule height\thicksize depth0pt}}%
  73. \def\hrulefill{\leaders\hrule\hfill}%
  74. \def\bigrulefill{\leaders\hrule height\thicksize depth0pt \hfill}%
  75. \def\ctr#1{\hfil\ #1\hfil}%
  76. \def\altctr#1{\hfil #1\hfil}%
  77. \def\vctr#1{\hfil\vbox to0pt{\vss\hbox{#1}\vss}\hfil}%
  78. %
  79. %  Here are things for controlling the width of the finished table.
  80. %
  81. \tablewidth=-\maxdimen%
  82. \spreadwidth=-\maxdimen%
  83. \def\tabskipglue{0pt plus 1fil minus 1fil}%
  84. %
  85. %  Stuff for centering or not.
  86. %
  87. \centertablestrue%
  88. \def\centeredtables{%
  89.    \centertablestrue%
  90. }%
  91. \def\noncenteredtables{%
  92.    \centertablesfalse%
  93. }%
  94. %
  95. %  \vctr vertically centers its argument in the row.
  96. %
  97. \parasize=4in%
  98. \long\def\para#1{%  Used to make little paragraphs out of one entry.
  99.    {%
  100.       \vtop{%
  101.          \hsize=\parasize%
  102.          \baselineskip14pt%
  103.          \lineskip1pt%
  104.          \lineskiplimit1pt%
  105.          \noindent #1%
  106.          \vrule width0pt depth6pt%
  107.       }%
  108.    }%
  109. }%
  110. %
  111. \gdef\ARGS{########}%  Produces the correct number of #'s in the preamble
  112. %                      by the time eveything is expanded and \halign sees
  113. %                      it.
  114. \gdef\headerARGS{####}%  Same as \ARGS, but used in \header macros.
  115. \def\@mpersand{&}%  Allows us to get alignment tab characters later
  116. %                   when we have made the character "&" an active macro.
  117. {\catcode`\|=13%  Make |'s locally active.
  118. \gdef\letbarzero{\let|0}%  Globally define a macro that allows us to
  119. %                          keep active |'s from being expanded in edef's.
  120. \gdef\letbartab{\def|{&&}}%
  121. \gdef\letvbbar{\let\vb|}%
  122. %  This \def will cause active |'s read by
  123. %                            \ruledtable to be converted into double
  124. %                            alignment tabs.
  125. }%  End of locally active |'s.
  126. %
  127. {\catcode`\&=4%  Make these alignment tabs.
  128. \def\ampskip{&\omit\hfil&}%  This local macro skips a vertical rule.
  129. \catcode`\&=13%  Now make &'s into active macros.
  130. \let&0%  This allows us to expand \ampskip in the next \xdef without
  131. %        attempting to expand the & and getting an "undefined control
  132. %        sequence" error.
  133. \xdef\letampskip{\def&{\ampskip}}%
  134. \gdef\letnovbamp{\let\novb&\let\tab&}
  135. %  This will cause active &'s read by
  136. %                                   \ruledtable to be converted into
  137. %                                   double tabs and an \omit'ted \vrule.
  138. }%  End of locally active &'s.
  139. %
  140. \def\begintable{%  Here we make |'s and &'s active characters so we can
  141. %                  interpret them as macros.  Note that this action is
  142. %                  true only until we encounter the matching \endgroup
  143. %                  token later at the end of the \ruledtable macro.
  144.    \begingroup%
  145.    \catcode`\|=13\letbartab\letvbbar%
  146.    \catcode`\&=13\letampskip\letnovbamp%
  147.    \def\multispan##1{%  We must redefine \multispan to count the number
  148. %                       of primary columns, not physical columns.
  149.       \omit \mscount##1%
  150.       \multiply\mscount\tw@\advance\mscount\m@ne%
  151.       \loop\ifnum\mscount>\@ne \sp@n\repeat%
  152.    }%  End of \multispan macro.
  153.    \def\|{%
  154.       &\omit\widevline&%
  155.    }%
  156.    \ruledtable%  Now we call \ruledtable to do the real work.
  157. }%  End of \begintable macro.
  158. %
  159. \long\def\ruledtable#1\endtable{%
  160. %
  161. %  This macro reads in the user's data entries
  162. %  and converts them into a ruled table.
  163. %
  164. %  Important note:  Many macros and parameters are re-defined here, and
  165. %  these must be kept local to the table macros to avoid conflict with
  166. %  their use outside of tables.  This is done by the \begingroup token
  167. %  macro \begintable and the \endgroup token at the end of
  168. %  this macro.
  169. %
  170.    \offinterlineskip%  Needed to make rules touch each other.
  171.    \tabskip 0pt%  Needed for same reason as \offinterlineskip.
  172.    \def\widevline{\vrule width\thicksize}%  Make outer \vrule's wider.
  173.    \def\endrow{\@mpersand\omit\hfil\crnorm\@mpersand}%
  174.    \def\crthick{\@mpersand\crnorm\thickrule\@mpersand}%
  175.    \def\crnorule{\@mpersand\crnorm\@mpersand}%
  176.    \let\nr=\crnorule%  A shorter abbreviation.
  177.    \def\endtable{\@mpersand\crnorm\thickrule}%
  178. %
  179.    \let\crnorm=\cr%  Allows us to use \cr for our own purposes.
  180. %
  181. %  Cause user-typed \cr's to follow a row with a \tablerule.
  182. %
  183.    \edef\cr{\@mpersand\crnorm\tablerule\@mpersand}%
  184. %
  185.    \the\tableLETtokens%  Get the user's extra \let's, if any.
  186. %
  187. %  Put the data entries into a token register so we can scan through them
  188. %  and see what the user is asking us to do.
  189. %
  190.    \tabletokens={}%  We add an extra alignment tab to the beginning
  191. %                       of the first row to allow for the first \vrule.
  192. %
  193. %  Now count how many rows are in the table and return the result in
  194. %  count register \nrows; do the same for columns, and return that
  195. %  in register \ncols.
  196. %
  197.    \countROWS\tabletokens\into\nrows%
  198.    \countCOLS\tabletokens\into\ncols%
  199. %
  200. %  Now do a little arithmetic to convert the number of primary columns
  201. %  into the number of physical columns that the alignment preamble must
  202. %  prepare for;  similarly for rows.
  203. %
  204.    \advance\ncols by -1%
  205.    \divide\ncols by 2%
  206.    \advance\nrows by 1%
  207. %
  208. %  Tell the user how many rows and columns we found in his data, if he
  209. %  wants to know.
  210. %
  211.    \iftableinfo %
  212.       \immediate\write16{[Nrows=\the\nrows, Ncols=\the\ncols]}%
  213.    \fi%
  214. %
  215. %  Now we actually go ahead and produce the table.
  216. %
  217.    \ifcentertables
  218.       \ifhmode \par\fi%  Make sure we are in vertical mode.
  219.       \tableline{%  The final table comes out as an \hbox of width the \hsize.
  220.       \hss%  The final table will be centered left-to-right.
  221.    \else %
  222.       \hbox{%
  223.    \fi
  224.       \vbox{%
  225.          \makePREAMBLE{\the\ncols}%  Generate the preamble.
  226.          \edef\next{\preamble}%  This line and the next line force the
  227.          \let\preamble=\next%    expansion of all \ARGS tokens into the
  228. %                                appropriate number of #'s.
  229.          \makeTABLE{\preamble}{\tabletokens}%  Go do the \halign here.
  230.       }%  End of \vbox.
  231.       \ifcentertables \hss}\else }\fi%  Finish the centering effect.
  232. %                                       It is important that no spaces
  233. %                                       follow the two `}' here.
  234. %  }%  End of \tableline
  235.    \endgroup%  Return all local macros and parameters to their outside
  236. %              values.
  237.    \tablewidth=-\maxdimen%  Reset \tablewidth to normal.
  238.    \spreadwidth=-\maxdimen% Same for \spreadwidth.
  239. }%  End of macro \ruledtable.
  240. %
  241. \def\makeTABLE#1#2{%  Does an \halign for the \ruledtable macro.
  242.    {%  Start of local parameter values.
  243. %
  244.    \let\ifmath0%     These macros would cause trouble if they were to be
  245.    \let\header0%     expanded in the following \xdef; we \let them be
  246.    \let\multispan0%  equal to a digit, because digits can't be expanded.
  247. %
  248. %  Set up the width specification here.
  249. %
  250.    \ncase=0%
  251.    \ifdim\tablewidth>-\maxdimen \ncase=1\fi%
  252.    \ifdim\spreadwidth>-\maxdimen \ncase=2\fi%
  253.    \relax%  This \relax is absolutely necessary, without it the following
  254. %           \ifcase will always take \ncase=0.
  255. %
  256.    \ifcase\ncase %
  257.       \widthspec={}%
  258.    \or %
  259.       \widthspec=\expandafter{\expandafter t\expandafter o%
  260.                  \the\tablewidth}%
  261.    \else %
  262.       \widthspec=\expandafter{\expandafter s\expandafter p\expandafter r%
  263.                  \expandafter e\expandafter a\expandafter d%
  264.                  \the\spreadwidth}%
  265.    \fi %
  266. %\out{Widthspec=O\the\widthspecE}%
  267. %\out{Preamble=O\preambleE}%
  268.    \xdef\next{%  We must force the preamble to be expanded BEFORE the
  269.       \halign\the\widthspec{%
  270. %        \halign is done;  this \edef\next{...}\next construction
  271. %                does the trick.
  272.       #1%  This is the preamble text.
  273. %
  274.       \noalign{\hrule height\thicksize depth0pt}%  Makes the top \hrule.
  275. %
  276.       \the#2\endtable%  This is the main body.
  277. %
  278. %     \noalign{\hrule height0.7pt depth0pt}%  Makes the last \hrule.
  279.       }%  End of \halign.
  280.    }%  End of \next.
  281.    }%  End of local values.
  282.    \next%  This \next must be outside of the local values, because now
  283. %          we want those troublesome macros in the \let's above to have
  284. %          their normal actions.
  285. }%  End of macro \makeTABLE.
  286. %
  287. \def\makePREAMBLE#1{%  This macro generates the necessary preamble for a
  288. %                      ruled table with #1 primary columns.
  289. %                      (Primary columns means the number of columns NOT
  290. %                       counting those used for vertical rules.)
  291.    \ncols=#1%  Get the number of columns desired.
  292.    \begingroup%  Start local parameter definitions.
  293.    \let\ARGS=0%  This is the key to the whole thing; it prevents \ARGS
  294. %                from being expanded in the following \edef's.
  295.    \edef\xtp{\widevline\ARGS\tabskip\tabskipglue%
  296.    &\ctr{\ARGS}\tstrut}%  A 1-column preamble.  Gets the sizing right.
  297.    \advance\ncols by -1%  One column has been generated; decrement the
  298. %                         counter.
  299.    \loop%  Append as many further columns as needed to the preamble.
  300.       \ifnum\ncols>0 %
  301.       \advance\ncols by -1%
  302.       \edef\xtp{\xtp&\vrule width\thinsize\ARGS&\ctr{\ARGS}}%
  303.    \repeat
  304.    \xdef\preamble{\xtp&\widevline\ARGS\tabskip0pt%
  305.    \crnorm}%  Adds the last \vrule.
  306.    \endgroup%  End of local parameters.
  307. }%  End of macro \makePREAMBLE.
  308. %
  309. \def\countROWS#1\into#2{%  This counts the number of rows in #1 by
  310. %                          looking for control sequences that end a row,
  311. %                          e.g., \cr, \crthick, etc., and puts the result
  312. %                          into count register #2.
  313.    \let\countREGISTER=#2%
  314.    \countREGISTER=0%
  315. %  \out{In countROWS:  tokens are O\the#1E}%
  316.    \expandafter\ROWcount\the#1\endcount%
  317. }%
  318. %
  319. \def\ROWcount{%
  320.    \afterassignment\subROWcount\let\next= %
  321. }%
  322. \def\subROWcount{%
  323. %  \out{In subROWcount:  next is O\meaning\nextE}%  Debugging aid.
  324.    \ifx\next\endcount %
  325.       \let\next=\relax%
  326.    \else%
  327.       \ncase=0%
  328.       \ifx\next\cr %
  329.          \global\advance\countREGISTER by 1%
  330.          \ncase=0%
  331.       \fi%
  332.       \ifx\next\endrow %
  333.          \global\advance\countREGISTER by 1%
  334.          \ncase=0%
  335.       \fi%
  336.       \ifx\next\crthick %
  337.          \global\advance\countREGISTER by 1%
  338.          \ncase=0%
  339.       \fi%
  340.       \ifx\next\crnorule %
  341.          \global\advance\countREGISTER by 1%
  342.          \ncase=0%
  343.       \fi%
  344.       \ifx\next\header %
  345. %     \out{In subROWcount:  next=header, ncase set=1}%
  346.          \ncase=1%
  347.       \fi%
  348. %     \out{In subROWcount:  ncase is O\the\ncaseE}%
  349.       \relax%
  350.       \ifcase\ncase %
  351.          \let\next\ROWcount%
  352. %        \out{subROWcount---> ncase=\the\ncase}%
  353.       \or %
  354.          \let\next\argROWskip%
  355. %        \out{subROWcount---> ncase=\the\ncase}%
  356.       \else %
  357.       \fi%
  358.    \fi%
  359. %  \out{subROWcount---> NEXT=\meaning\next}%
  360.    \next%
  361. }%  End of macro \subROWcount.
  362. %
  363. \def\counthdROWS#1\into#2{%
  364. \dvr{10}%
  365.    \let\countREGISTER=#2%
  366.    \countREGISTER=0%
  367. \dvr{11}%
  368. %  \out{In counthdROWS:  tokens are O\the#1E}%
  369. \dvr{13}%
  370.    \expandafter\hdROWcount\the#1\endcount%
  371. \dvr{12}%
  372. }%
  373. %
  374. \def\hdROWcount{%
  375.    \afterassignment\subhdROWcount\let\next= %
  376. }%
  377. \def\subhdROWcount{%
  378. %\out{In subhdROWcount:  next is O\meaning\nextE}%
  379.    \ifx\next\endcount %
  380.       \let\next=\relax%
  381.    \else%
  382.       \ncase=0%
  383.       \ifx\next\cr %
  384.          \global\advance\countREGISTER by 1%
  385.          \ncase=0%
  386.       \fi%
  387.       \ifx\next\endrow %
  388.          \global\advance\countREGISTER by 1%
  389.          \ncase=0%
  390.       \fi%
  391.       \ifx\next\crthick %
  392.          \global\advance\countREGISTER by 1%
  393.          \ncase=0%
  394.       \fi%
  395.       \ifx\next\crnorule %
  396.          \global\advance\countREGISTER by 1%
  397.          \ncase=0%
  398.       \fi%
  399.       \ifx\next\header %
  400. %\out{In subhdROWcount:  next=header, ncase set=1}%
  401.          \ncase=1%
  402.       \fi%
  403. %\out{In subhdROWcount:  ncase is O\the\ncaseE}%
  404. \relax%
  405.       \ifcase\ncase %
  406.          \let\next\hdROWcount%
  407. %\out{subhdROWcount---> ncase=\the\ncase}%
  408.       \or%
  409.          \let\next\arghdROWskip%
  410. %\out{subhdROWcount---> ncase=\the\ncase}%
  411.       \else %
  412.       \fi%
  413.    \fi%
  414. %\out{subhdROWcount---> NEXT=\meaning\next}%
  415.    \next%
  416. }%
  417. %
  418. {\catcode`\|=13\letbartab
  419. \gdef\countCOLS#1\into#2{%
  420. %  \out{In countCOLS:  tokens are O\the#1E}
  421.    \let\countREGISTER=#2%
  422.    \global\countREGISTER=0%
  423.    \global\multispancount=0%
  424.    \global\firstrowtrue
  425.    \expandafter\COLcount\the#1\endcount%
  426.    \global\advance\countREGISTER by 3%
  427.    \global\advance\countREGISTER by -\multispancount
  428. %  \out{countCOLS-->O\the\countREGISTERE}
  429. }%
  430. %
  431. \gdef\COLcount{%
  432.    \afterassignment\subCOLcount\let\next= %
  433. }%
  434. {\catcode`\&=13%
  435. \gdef\subCOLcount{%
  436. %\out{In subCOLcount: next is O\meaning\nextE}
  437.    \ifx\next\endcount %
  438.       \let\next=\relax%
  439.    \else%
  440.       \ncase=0%
  441.       \iffirstrow
  442.          \ifx\next& %
  443.             \global\advance\countREGISTER by 2%
  444.             \ncase=0%
  445.          \fi%
  446.          \ifx\next\span %
  447.             \global\advance\countREGISTER by 1%
  448.             \ncase=0%
  449.          \fi%
  450.          \ifx\next| %
  451.             \global\advance\countREGISTER by 2%
  452.             \ncase=0%
  453.          \fi
  454.          \ifx\next\|
  455.             \global\advance\countREGISTER by 2%
  456.             \ncase=0%
  457.          \fi
  458.          \ifx\next\multispan
  459.             \ncase=1%
  460.             \global\advance\multispancount by 1%
  461.          \fi
  462.          \ifx\next\header
  463.             \ncase=2%
  464.          \fi
  465.          \ifx\next\cr       \global\firstrowfalse \fi
  466.          \ifx\next\endrow   \global\firstrowfalse \fi
  467.          \ifx\next\crthick  \global\firstrowfalse \fi
  468.          \ifx\next\crnorule \global\firstrowfalse \fi
  469.       \fi%  End of \iffirstrow.
  470. \relax%\out{subCOL-->  ncase=O\the\ncaseE}
  471. % \out{subCOL-->  next=\meaning\next}
  472.       \ifcase\ncase %
  473.          \let\next\COLcount%
  474.       \or %
  475.          \let\next\spancount%
  476.       \or %
  477.          \let\next\argCOLskip%
  478.       \else %
  479.       \fi %
  480.    \fi%
  481. %  \out{subCOL-->  countREGISTER=O\the\countREGISTERE}
  482.    \next%
  483. }%
  484. \gdef\argROWskip#1{%
  485. %  Deletes the next balanced, undelimited argument from a
  486. %                 token list.
  487. % \out{---> Entering argROWskip <---}
  488. % \out{In argROWskip:  deleted arg is O#1E}%
  489.    \let\next\ROWcount \next%
  490. }%  End of macro \argskip.
  491. \gdef\arghdROWskip#1{%
  492. %  Deletes the next balanced, undelimited argument from a
  493. %                 token list.
  494. % \out{---> Entering arghdROWskip <---}
  495. % \out{In arghdROWskip:  deleted arg is O#1E}%
  496.    \let\next\ROWcount \next%
  497. }%  End of macro \arghdROWskip.
  498. \gdef\argCOLskip#1{%
  499. %  Deletes the next balanced, undelimited argument from a
  500. %                 token list.
  501. % \out{---> Entering argCOLskip <---}
  502. % \out{In argCOLskip:  deleted arg is O#1E}%
  503.    \let\next\COLcount \next%
  504. }%  End of macro \argskip.
  505. }%  End of active &'s.
  506. }%  End of active |'s.
  507. \def\spancount#1{%\out{spancount--->\meaning#1}
  508.    \nspan=#1\multiply\nspan by 2\advance\nspan by -1%
  509.    \global\advance \countREGISTER by \nspan
  510. %  \out{number spancount--->\the\nspan; \the\countREGISTER}
  511.    \let\next\COLcount \next}%
  512. %
  513. %\def\dvr#1{\vrule width 1.0pt depth 0pt height 12pt$_{#1}$}
  514. \def\dvr#1{\relax}%
  515. % \omit\hfil%
  516. % \parindent=0pt\hsize=1.1in\valign{%
  517. % \vfil#\vfil&\vfil#\vfil\cr\hfil\hbox{\ Added to\ }\hfil&%
  518. % \hfil\hbox{\ empty events\ }\hfil\cr}\hfil%
  519. \def\header#1{%
  520. \dvr{1}{\let\cr=\@mpersand%
  521. \hdtks={#1}%
  522. %\out{In header:  hdtks=O\the\hdtksE}%
  523. \counthdROWS\hdtks\into\hdrows%
  524. \advance\hdrows by 1%
  525. \ifnum\hdrows=0 \hdrows=1 \fi%
  526. %\out{In header:  Nhdrows=O\the\hdrowsE}%
  527. \dvr{5}\makehdPREAMBLE{\the\hdrows}%
  528. %\out{In header:  headerpreamble=O\headerpreambleE}%
  529. \dvr{6}\getHDdimen{#1}%
  530. %\out{In header:  hdsize=O\the\hdsizeE}%
  531. %\striplastCR{#1}%
  532. {\parindent=0pt\hsize=\hdsize{\let\ifmath0%
  533. \xdef\next{\valign{\headerpreamble #1\crnorm}}}\dvr{7}\next\dvr{8}%
  534. }%
  535. }\dvr{2}}%  End of macro \header.
  536. %\def\striplastCR#1\cr{\xdef\headerbody{#1}}%
  537. \def\makehdPREAMBLE#1{%This macro generates the necessary preamble for a
  538. \dvr{3}%
  539. %                      ruled table with \ncols primary columns.
  540. %                      (Primary columns means the number of columns NOT
  541. %                       counting those used for vertical rules.
  542. \hdrows=#1%  Get the number of columns desired.
  543. {%  Start local parameter definitions.
  544. \let\headerARGS=0%
  545. %  This is the key to the whole thing; it prevents \ARGS
  546. \let\cr=\crnorm%
  547. %                from being expanded in the followin \edef's.
  548. \edef\xtp{\vfil\hfil\hbox{\headerARGS}\hfil\vfil}%
  549. \advance\hdrows by -1%  One row has been generated; decrement the
  550. %                         counter.
  551. \loop%  Append as many further rows as needed to the preamble.
  552. \ifnum\hdrows>0%
  553. \advance\hdrows by -1%
  554. \edef\xtp{\xtp&\vfil\hfil\hbox{\headerARGS}\hfil\vfil}%
  555. \repeat%
  556. \xdef\headerpreamble{\xtp\crcr}%
  557. }%  End of local parameters.
  558. \dvr{4}}%  End of \makehdPREAMBLE.
  559. %
  560. \def\getHDdimen#1{%
  561. %\out{In getHDdimen:  Arg 1=O#1E}%
  562. \hdsize=0pt%
  563. \getsize#1\cr\end\cr%
  564. }%  End of macro getHDdimen.
  565. \def\getsize#1\cr{%
  566. %\out{In getsize:  Arg 1=O#1E}%
  567. %  Here we have to check arg#1 and see if the first token in #1 is an
  568. %    \end; if so, we stop, else we check the width of arg#1.
  569. %  We recall that each arg#1 will be terminated with a \cr token.
  570. \endsizefalse\savetks={#1}%
  571. %\out{In getsize:  the savetks = O\the\savetksE}%
  572. \expandafter\lookend\the\savetks\cr%
  573. %\out{In getsize:  ifendsize = O\meaning\ifendsizeE}%
  574. \relax \ifendsize \let\next\relax \else%
  575. \setbox\hdbox=\hbox{#1}\newhdsize=1.0\wd\hdbox%
  576. \ifdim\newhdsize>\hdsize \hdsize=\newhdsize \fi%
  577. %\out{In getsize:  hdsize=O\the\hdsizeE}%
  578. %\out{In getsize:  newhdsize=O\the\newhdsizeE}%
  579. \let\next\getsize \fi%
  580. \next%
  581. }%
  582. \def\lookend{\afterassignment\sublookend\let\looknext= }%
  583. \def\sublookend{\relax%
  584. %\out{In sublookend:  looknext = O\looknextE}%
  585. \ifx\looknext\cr %
  586. %\out{In sublooknext:  looknext=cr}%
  587. \let\looknext\relax \else %
  588. %\out{In sublooknext:  looknext/=cr}%
  589.    \relax
  590.    \ifx\looknext\end \global\endsizetrue \fi%
  591.    \let\looknext=\lookend%
  592.     \fi \looknext%
  593. }%
  594. %
  595. %  Allow the user to make his own names for crthick, etc.
  596. %
  597. \def\tablelet#1{%
  598.    \tableLETtokens=\expandafter{\the\tableLETtokens #1}%
  599. }%
  600. \catcode`\@=12%  Change @'s back to their normal category code.
  601. %
  602.